\documentclass[E:/GsjzTle/main/main.tex]{subfiles}


\begin{document}

\begin{itemize}
\item
  \(pushdown\) 的时候需要判断区间是否被打上过标记
\item
  \(lazy\) 需要赋初值
\end{itemize}

\begin{lstlisting}
const int N = 3e5 + 10;
const int INF = (0x3f3f3f3f3f3f3f3fll);
struct Tree{
	int l , r , sum , lazy; // 注意要赋予初值 
}tree[N << 2];
void push_up(int rt)
{
	tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum; 
}
void push_down(int rt)
{
	int &x = tree[rt].lazy , l = tree[rt].l , r = tree[rt].r;
	if(x != -INF)  // 需要判断是否被打上过标记  
	{
		int mid = l + r >> 1;
		tree[rt << 1].sum = x * (mid - l + 1) , tree[rt << 1 | 1].sum = (r - mid) * x;
		tree[rt << 1].lazy = tree[rt << 1 | 1].lazy = x;
	}
	x = -INF;
}
void build(int l , int r , int rt , int *a)
{
	tree[rt].l = l , tree[rt].r = r , tree[rt].lazy = -INF;
	if(l == r) 
	{
		tree[rt].sum = a[l];
		return ;
	}
	int mid = l + r >> 1;
	build(l , mid , rt << 1 , a);
	build(mid + 1 , r , rt << 1 | 1 , a);
	push_up(rt);
}
void update_range(int L , int R , int rt , int val)
{
	int l = tree[rt].l , r = tree[rt].r;
	if(L <= l && r <= R) 
	{
		tree[rt].sum = (r - l + 1) * val;
		tree[rt].lazy = val;
		return ;
	}
	push_down(rt);
	int mid = l + r >> 1;
	if(L <= mid) update_range(L , R , rt << 1 , val);
	if(R  > mid) update_range(L , R , rt << 1 | 1 , val);
	push_up(rt);
}

int query_range(int L , int R , int rt)
{
	int l = tree[rt].l , r = tree[rt].r;
	if(L <= l && r <= R) return tree[rt].sum;
	push_down(rt);
	int mid = l + r >> 1 , ans = 0;
	if(L <= mid) ans += query_range(L , R , rt << 1);
	if(R  > mid) ans += query_range(L , R , rt << 1 | 1);
	return ans;
}

int n , m , a[N];

signed main()
{
	ios::sync_with_stdio(false);
	
	cin >> n ;
	
	rep(i , 1 , n) cin >> a[i];
	
	build(1 , n , 1 , a);
	
	cin >> m;
	
	while(m --)
	{
		int op , l , r , k;
		
		cin >> op >> l >> r;
		
		if(!op) cout << query_range(l , r , 1) << '\n';
		
		else
		{
			cin >> k;
			
			update_range(l , r , 1 , k);
		}
	}
	
	return 0;
}
\end{lstlisting}

\end{document}
